#    Copyright 2012 New Mexico EPSCoR
#
#    This file is part of Teacher's P.E.T.
#
#    Teacher's P.E.T. is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Teacher's P.E.T. is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Teacher's P.E.T..  If not, see <http://www.gnu.org/licenses/>.

from apps.forum.models import *
from apps.course.functions import course_reverse

from base import ForumTestCaseBase

# Base classes with common tests
class ForumTestCaseForumBase(ForumTestCaseBase):
    """
     - Bad course participant results in redirect to course homepage
     - User banned from viewing forum results in redirect to course homepage
     
     In all base class functions, check if function is None. If so, quit the test
     so that only "leaf" classes actually perform testing
    """
    function_file = "apps.forum.views.forum"
    function_name = None
    function_arguments = None
    def __get_view__(self):
        if not self.function_name: return None
        return "%s.%s" % (self.function_file,self.function_name)
    
    ban_level = ForumBan.BAN_FORUM
    
    def test_bad_course_participant(self):
        if self.function_name:
            print "testing bad_course_participant"
            response = self.student1.client.post(course_reverse(self.__get_view__(),kwargs=self.function_arguments if self.function_arguments else None))
            self.assertRedirects(response,course_reverse('course_index'))
            self.assertInMessages(response,"requires course authentication")

class ForumTestCasePagedView(ForumTestCaseForumBase):
    """
     - Page out of range results in forcing page to be in range
     
     In all base class functions, check if function is None. If so, quit the test
     so that only "leaf" classes actually perform testing
    """    
    pass

class ForumTestCaseModifyEntry(ForumTestCaseForumBase):
    """
    For fxns that modify entries, they have the following in common:
     - Invalid entry with no thread results in redirect to forum_view_threads
     - Invalid entry with good thread results in redirect to forum_view_entries
     - Invalid thread results in redirect to forum_view_threads
    
     In all base class functions, check if function is None. If so, quit the test
     so that only "leaf" classes actually perform testing
    """
    pass


#Actual testing classes
class ForumTestCaseViewThreads(ForumTestCasePagedView):
    """
    Needs page testing, bad cp testing, ban testing - ForumTestCaseForumBase
     - No threads does not result in an error
     - Success shows template forum/forum/list_threads.html
    """
    function_name = "view_threads"
    function_arguments = {"page":1}
    pass

class ForumTestCaseViewEntries(ForumTestCasePagedView):
    """
    Needs page testing, bad cp testing, ban testing - ForumTestCaseForumBase
     - No thread_id results in redirect to forum_view_threads
     - thread_id doesn't exist results in redirect to forum_view_threads
     - student tries to access hidden thread results in redirect to forum_view_threads
     - success shows template forum/forum/list_entries.html
    """
    function_name = "view_entries"
    function_arguments = {"thread_id":1,"page":1}
    pass

class ForumTestCaseEditEntry(ForumTestCaseForumBase):
    """
    Doesn't need page testing, needs bad cp testing, ban testing - ForumTestCaseForumBase
     - Editing invalid entry results in redirect to forum_view_threads
     - Editing another user's entry results in redirect to forum_view_threads
     - Adding entry to invalid thread results in redirect to forum_view_threads
     - Quoting an entry from an invalid thread results in redirect to forum_view_threads
     - Creating a thread with an empty title
     - Creating a thread with an empty entry
     - Creating a thread with a repeat name
     - Success shows forum/forum/edit_entry.html
    """
    function_name = "edit_entry"
    function_arguments = {"thread_id":1}
    def test_ForumThread_creation_error_empty_title(self):
        #Empty title
        response = self.student1.client.post(course_reverse('forum_create_thread',self.course1),{'title':"",'entry':"I think that I should be voted best fake student ever!"})
        self.assertEqual(response.status_code,200)
        self.assertFormError(response,'ThreadForm','title','This field is required.','Thread created with empty title')
        
    def test_ForumThread_creation_error_empty_entry(self):
        #empty entry
        response = self.student1.client.post(course_reverse('forum_create_thread',self.course1),{'title':"Student1's Thread",'entry':""})
        self.assertEqual(response.status_code,200)
        self.assertFormError(response,'EntryForm','entry','This field is required.','Entry created with empty entry')

    def test_ForumThread_creation_success(self):
        #good thread
        response = self.student1.client.post(course_reverse('forum_create_thread',self.course1),{'title':"Student1's Thread",'entry':"I think that I should be voted best fake student ever!"})
        self.assertEqual(response.status_code,302)
        self.assertNotEqual(ForumThread.objects.filter(forum=self.course1.forum,title="Student1's Thread"),None)
        
    def test_ForumThread_creation_error_exists(self):
        #good thread
        response = self.student1.client.post(course_reverse('forum_create_thread',self.course1),{'title':"Student1's Thread",'entry':"I think that I should be voted best fake student ever!"})
        #Repeat thread
        response = self.student1.client.post(course_reverse('forum_create_thread',self.course1),{'title':"Student1's Thread",'entry':"I think that I should be voted best fake student ever!"})
        self.assertEqual(response.status_code,200)
        self.assertFormError(response,'ThreadForm','title','A thread with this title already exists in the forum','Entry created with empty entry')

class ForumTestCaseFlagEntry(ForumTestCaseModifyEntry):
    """
    Doesn't need page testing, needs bad cp testing, ban testing - ForumTestCaseForumBase
    Modifies entry - ForumTestCaseModifyEntry (derived from ForumTestCaseForumBase)
     - Repeat moderator flagging results in redirect to forum_view_entries
     - Success redirects to forum_view_entries
    """
    function_name = "flag_entry"
    function_arguments = {"thread_id":1,"entry_number":1}
    pass

class ForumTestCaseLikeEntry(ForumTestCaseModifyEntry):
    """
    Doesn't need page testing, needs bad cp testing, ban testing - ForumTestCaseForumBase
    Modifies entry - ForumTestCaseModifyEntry (derived from ForumTestCaseForumBase)
     - Repeat liking results in redirect to forum_view_entries
     - Success redirects to forum_view_entries
    """
    function_name = "like_entry"
    function_arguments = {"thread_id":1,"entry_number":1}
    pass

class ForumTestCaseAttachEntry(ForumTestCaseModifyEntry):
    """
    Doesn't need page testing, needs bad cp testing, ban testing - ForumTestCaseForumBase
    Modifies entry - ForumTestCaseModifyEntry (derived from ForumTestCaseForumBase)
     - Attaching to other user's entry results in redirect to forum_view_threads
     - Success shows template forum/forum/attach_entry.html
    """
    function_name = "attach_entry"
    pass

class ForumTestCaseDownloadAttachment(ForumTestCaseModifyEntry):
    """
    Doesn't need page testing, needs bad cp testing, ban testing - ForumTestCaseForumBase
    Modifies entry - ForumTestCaseModifyEntry (derived from ForumTestCaseForumBase)
     - Success serves file
    """
    function_name = "download_attachment"
    pass

class ForumTestCaseDeleteAttachment(ForumTestCaseModifyEntry):
    """
    Doesn't need page testing, needs bad cp testing, ban testing - ForumTestCaseForumBase
    Modifies entry - ForumTestCaseModifyEntry (derived from ForumTestCaseForumBase)
     - Success redirects to forum_attach_entry
    """
    function_name = "delete_attachment"
    pass

